package org.fox.beetl.ext.spring.utils;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;

/**
 * ApplicationContext生命周期事件监听器
 *
 * @author Chen Rui
 */
public class ApplicationContextLifecycleEventListener implements ApplicationListener<ApplicationContextEvent> {
	// 日志
	private static final Log LOG = LogFactory.getLog(ApplicationContextLifecycleEventListener.class);

	/* ----- ----- ----- ----- 其他方法 ----- ----- ----- ----- */
	/**
	 * 处理ApplicationContext的生命周期处理事件
	 *
	 * @param event
	 */
	@Override
	public void onApplicationEvent(ApplicationContextEvent event) {
		// 获取应用程序上下文
		ApplicationContext applicationContext = event.getApplicationContext();
		LOG.info(String.format("ApplicationContext生命周期事件(%s): %s",
				applicationContext != null ? applicationContext.getId() : "null", event.getClass().getSimpleName()));

		if (applicationContext != null) {
			if ((event instanceof ContextStoppedEvent) || (event instanceof ContextClosedEvent)) {
				removeApplicationContext(applicationContext.getId());
			} else if ((event instanceof ContextRefreshedEvent) || (event instanceof ContextStartedEvent)) {
				setApplicationContext(applicationContext);
			}
		}
	}

	/* ----- ----- ----- ----- ApplicationContext管理 ----- ----- ----- ----- */
	/**
	 * application应用程序上下文
	 */
	private static Map<String, ApplicationContext> applicationContextPool = new HashMap<String, ApplicationContext>();

	/**
	 * 添加ApplicationContext对象
	 *
	 * @param applicationContext
	 */
	private static synchronized void setApplicationContext(ApplicationContext applicationContext) {
		applicationContextPool.put(applicationContext.getId(), applicationContext);
	}

	/**
	 * 删除ApplicationContext对象
	 *
	 * @param id
	 */
	private static synchronized void removeApplicationContext(String id) {
		applicationContextPool.remove(id);
	}

	/**
	 * 获取ID指定的ApplicationContext
	 *
	 * @param id
	 * @return
	 */
	public static synchronized ApplicationContext getApplicationContext(String id) {
		return applicationContextPool.get(id);
	}
}
